﻿using System;
using System.Net;
using System.Linq;
//using MEFedMVVM.ViewModelLocator;
//using Cinch;

using Microsoft.Maps.MapControl;
using System.Collections.ObjectModel;
using System.Collections;
using System.Xml;
using System.IO;
using System.ComponentModel;
using System.Windows;


using BusinessApplication.Web;
using System.ServiceModel.DomainServices.Client;
using BusinessApplication.Web.Services;
using BusinessApplication.Model;
using BusinessApplication.Web.Model;
using GalaSoft.MvvmLight;
using BusinessApplication.Controls;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Shapes;
namespace BusinessApplication.Models
{
    /// <summary>
    /// Provides data for views displaying earthquake information.
    /// </summary>
    public class LocationViewModel : ViewModelBase
    {

        #region Events
        // Declare the PropertyChanged event
        public event PropertyChangedEventHandler PropertyChanged;
        public DelegateCommand MClickCommand { get; set; }

        #endregion

        #region Events Methods
        protected virtual void OnPropertyChanged(PropertyChangedEventArgs e)
        {
            if (this.PropertyChanged != null)
                this.PropertyChanged(this, e);
        }

        private void loadOperation_Completed(object sender, EventArgs e)
        {
            LoadOperation<LocationItem> list = sender as LoadOperation<LocationItem>;
            if (list != null)
            {
                var cnt = 0;
                //              geocodeResults = new ServiceReferenceGeo.GeocodeResult[list.Entities.Count()];

                foreach (var item in list.Entities)
                {
                    var mapItem = new MapItem
                    {
                        Location = new Location(item.Lat, item.Lng),
                        Lat = item.Lat,
                        Lng = item.Lng,
                        Id = item.Id.ToString(),
                        Title = item.Title,
                        Address = item.Address
                    };
                    Locations.Add(mapItem);
                    //              if (item.Lng == 0 || item.Lat == 0)
                    //                    Geocode(mapItem, cnt);
                    //            cnt++;
                }
            }
        }

        private void geocodeService_GeocodeCompleted(object sender, ServiceReferenceGeo.GeocodeCompletedEventArgs e)
        {
            // Retrieve the user state of this response (the ‘waypoint index’) to identify which geocode request 
            //   it corresponds to.
            int waypointIndex = System.Convert.ToInt32(e.UserState);

            // Retrieve the GeocodeResult for this response and store it in the global variable geocodeResults, using
            //   the waypoint index to position it in the array.
            geocodeResults[waypointIndex] = e.Result.Results[0];

            // Look at each element in the global gecodeResults array to figure out if more geocode responses still 
            //   need to be returned.

            foreach (ServiceReferenceGeo.GeocodeResult gr in geocodeResults)
            {
                if (gr != null)
                {
                    var all = Locations.Where(c => c.Address == gr.DisplayName);
                    foreach (var item in all)
                    {
                        var myLocation = new MapItem();
                        myLocation.Id = item.Id;
                        myLocation.Lat = gr.Locations[0].Latitude;
                        myLocation.Lat = gr.Locations[0].Longitude;
                        myLocation.Location = new Location(gr.Locations[0].Latitude, gr.Locations[0].Longitude);
                        myLocation.Title = item.Title;
                        myLocation.Address = item.Address;

                        Locations.Remove(item);
                        Locations.Add(myLocation);

                    }
                }
            }


        }

        #endregion

        public LocationViewModel()
        {
            Context = new MapContext();
            Initialize();
            MClickCommand = new DelegateCommand(PerformClickAction);
            Load();
        }


        public void PerformClickAction(object sender)
        {
            

            MouseButtonEventArgs e = (MouseButtonEventArgs)sender;
            var sharp = (Ellipse)e.OriginalSource;
            var map = (MapItem)sharp.DataContext;

            MessageBox.Show(map.Title);

        }


        #region Private Methods



        // This is the global internal variable where results are stored. These are accessed later to calculate the route.
        internal ServiceReferenceGeo.GeocodeResult[] geocodeResults;
        private void Geocode(MapItem mapItem, int waypointIndex)
        {

            // Create the service variable and set the callback method using the GeocodeCompleted property.
            ServiceReferenceGeo.GeocodeServiceClient geocodeService = new ServiceReferenceGeo.GeocodeServiceClient("BasicHttpBinding_IGeocodeService");
            geocodeService.GeocodeCompleted += new EventHandler<ServiceReferenceGeo.GeocodeCompletedEventArgs>(geocodeService_GeocodeCompleted);

            // Set the credentials and the geocode query, which could be an address or location.
            ServiceReferenceGeo.GeocodeRequest geocodeRequest = new ServiceReferenceGeo.GeocodeRequest();
            geocodeRequest.Credentials = new Credentials();
            geocodeRequest.Credentials.ApplicationId = (new ApplicationIdCredentialsProvider("AhYfF92PBowAMewWaHB6VxExehTnXmv9GsvmWXsuX1JqIqmbyG3pf4HmI0YcdA9m")).ApplicationId;
            geocodeRequest.Query = mapItem.Address;

            // Make the asynchronous Geocode request, using the ‘waypoint index’ as 
            //   the user state to track this request and allow it to be identified when the response is returned.
            geocodeService.GeocodeAsync(geocodeRequest, waypointIndex);
        }
        // This is the Geocode request callback method.

        private void Initialize()
        {
            MapCenter = new Location(20, -170);
            ZoomLevel = 2;
        }

        private void Load()
        {
            Locations.Add(new MapItem
               {
                   Id = "10003",
                   Title = "Jack",
                   Location = new Location(40.941352, -73.871310)
               });

            Locations.Add(new MapItem
            {
                Id = "10001",
                Title = "Aaron",
                Location = new Location(43.778926, -73.958068)
            });

            loadOperation = Context.Load<LocationItem>(Context.GetLocationsQuery());
            loadOperation.Completed += new EventHandler(loadOperation_Completed);
        }

        #endregion Private Methods

        #region Properties

        public MapContext Context;
        public LoadOperation<LocationItem> loadOperation = null;

        private ObservableCollection<MapItem> _Locations = new ObservableCollection<MapItem>();
        public ObservableCollection<MapItem> Locations
        {

            get { return this._Locations; }
            set
            {
                if (this._Locations == value) return;
                this._Locations = value;
                this.OnPropertyChanged(new PropertyChangedEventArgs("Locations"));
            }
        }

        private Location _MapCenter;
        public Location MapCenter
        {
            get { return _MapCenter; }
            set
            {
                _MapCenter = value;
                //  onPropertyChanged(this, "MapCenter");

            }
        }

        private double _ZoomLevel;
        public double ZoomLevel
        {
            get { return _ZoomLevel; }
            set
            {
                _ZoomLevel = value;
                // onPropertyChanged(this, "ZoomLevel");
            }
        }

        #endregion Properties
    }
}
